home *** CD-ROM | disk | FTP | other *** search
- /*
- * This library is mainly intended to demonstrate how to program a sub
- * library.
- */
-
- #define VERSION 1
-
- #include <xpk/xpksub.h>
- #include <exec/memory.h>
- #include <pragma/exec_lib.h>
-
- #define SDI_TO_ANSI
- #include "SDI_ASM_STD_protos.h"
-
- #ifdef __MAXON__
- #define __asm
- #endif
-
- #define SCANBUFLEN 32768
-
- /*
- * Pack a chunk
- */
-
- struct NukeData {
- APTR inbuf;
- APTR outbuf;
- APTR last;
- APTR next;
- ULONG cwri;
- ULONG uwri;
- ULONG uend;
- ULONG delpos;
- UWORD ulen;
- UWORD clen;
- UWORD ustop;
- UWORD ustart;
- UWORD ucount;
- UWORD scanrange;
- UWORD room1;
- UWORD room2;
- UWORD room4;
- UWORD roomN;
- UWORD data1;
- UWORD data2;
- ULONG data4;
- ULONG dataN;
- ULONG dest1;
- ULONG dest2;
- ULONG dest4;
- ULONG destN;
- ULONG dummy;
- ULONG contbuf;
- ULONG flags;
- };
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- LONG __asm AsmPack (register __a4 struct NukeData *ND);
- STRPTR __asm AsmUnpack(register __a1 STRPTR wread, register __a4 STRPTR bread,
- register __a0 STRPTR dst, register __a2 STRPTR end);
- #ifdef __cplusplus
- }
- #endif
-
- #define PACKMEM (65536+SCANBUFLEN)*sizeof(UWORD)+sizeof(struct NukeData)+SCANBUFLEN
- #define UNPACKMEM SCANBUFLEN
- #define A3000 XPKMF_A3000SPEED
-
- static struct XpkMode DukeMode = {
- NULL, // Next mode
- 100, // Handles up to
- A3000, // Flags
- PACKMEM, // Packing memory
- UNPACKMEM, // Unpacking memory
- 36, // Packing speed
- 630, // Unpacking speed
- 454, // Compression ratio
- 0, // Reserved
- "normal", // Description
- };
-
- static struct XpkInfo DukeInfo = {
- 1, /* info version */
- VERSION, /* lib version */
- 0, /* master vers */
- 1, /* ModesVersion */
- (STRPTR) "DUKE", /* short name */
- (STRPTR) "Duke", /* long name */
- (STRPTR) "NUKE with a delta preprocessor", /* Description */
- 0x44554B45, /* 'DUKE', 4 letter ID */
- XPKIF_PK_CHUNK | /* flags */
- XPKIF_UP_CHUNK,
- 30000, /* max in chunk */
- 10, /* min in chunk */
- 30000, /* def in chunk */
- (STRPTR) "Duking", /* pk message */
- (STRPTR) "Unduking", /* up message */
- (STRPTR) "Duked", /* pk past msg */
- (STRPTR) "Unduked", /* up past msg */
- 50, /* DefMode */
- 0, /* Pad */
- &DukeMode, /* ModeDesc */
- 0, /* MinModeDesc */
- 0, /* MaxModeDesc */
- 0,0,0,0 /* reserved */
- };
-
- void DoDelta(STRPTR dst, STRPTR src, LONG len)
- {
- UBYTE a=0, b=0;
-
- if (len>0) {
- switch (len & 7) {
- do {
- case 0: *dst++ = (UBYTE) ((b=*src++) - a);
- case 7: *dst++ = (UBYTE) ((a=*src++) - b);
- case 6: *dst++ = (UBYTE) ((b=*src++) - a);
- case 5: *dst++ = (UBYTE) ((a=*src++) - b);
- case 4: *dst++ = (UBYTE) ((b=*src++) - a);
- case 3: *dst++ = (UBYTE) ((a=*src++) - b);
- case 2: *dst++ = (UBYTE) ((b=*src++) - a);
- case 1: *dst++ = (UBYTE) ((a=*src++) - b);
- } while ((len-=8)>0);
- }
- }
- }
-
- void UndoDelta(STRPTR dst, STRPTR src, LONG len)
- {
- UBYTE l = 0;
-
- if (len > 0) {
- switch (len & 7) {
- do {
- case 0: *dst++ = (l+=*src++);
- case 7: *dst++ = (l+=*src++);
- case 6: *dst++ = (l+=*src++);
- case 5: *dst++ = (l+=*src++);
- case 4: *dst++ = (l+=*src++);
- case 3: *dst++ = (l+=*src++);
- case 2: *dst++ = (l+=*src++);
- case 1: *dst++ = (l+=*src++);
- } while ((len-=8)>0);
- }
- }
- }
-
- /*
- * Returns an info structure about our packer
- */
-
- #ifdef __cplusplus
- extern "C"
- #endif
-
- struct XpkInfo *XpksPackerInfo(void)
- {
- return &DukeInfo;
- }
-
- #ifdef __cplusplus
- extern "C"
- #endif
-
- #define LASTSIZE (65536*sizeof(UWORD))
- #define NEXTSIZE (SCANBUFLEN*sizeof(UWORD))
-
- void __asm XpksPackFree(register __a0 struct XpkSubParams *xpar)
- {
- struct NukeData *ND = (struct NukeData *) xpar->xsp_Sub[0];
-
- if(xpar->xsp_Sub[1])
- {
- FreeMem((APTR) xpar->xsp_Sub[1], SCANBUFLEN);
- xpar->xsp_Sub[1] = 0;
- }
- if(ND)
- {
- if(ND->last) FreeMem(ND->last, LASTSIZE);
- if(ND->next) FreeMem(ND->next, NEXTSIZE);
- FreeMem(ND, sizeof(struct NukeData));
- xpar->xsp_Sub[0] = 0;
- }
- }
-
-
- struct NukeData *alloctabs(struct XpkSubParams *xpar)
- {
- struct NukeData *ND;
-
- if ((xpar->xsp_Sub[0] = (LONG) (ND = (struct NukeData*) AllocMem(sizeof(struct NukeData),MEMF_CLEAR))) &&
- (ND->last = AllocMem(LASTSIZE,0)) &&
- (ND->next = AllocMem(NEXTSIZE,0)) &&
- (xpar->xsp_Sub[1] = (LONG) AllocMem(SCANBUFLEN,0))) {
- return ND;
- }
- else
- {
- XpksPackFree(xpar);
- return 0;
- }
- }
-
- #ifdef __cplusplus
- extern "C"
- #endif
-
- LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar )
- {
- struct NukeData *ND=(struct NukeData *)xpar->xsp_Sub[0];
-
- if (!ND)
- if (!(ND=alloctabs(xpar)))
- return XPKERR_NOMEM;
-
- DoDelta((STRPTR)xpar->xsp_Sub[1], (STRPTR) xpar->xsp_InBuf, xpar->xsp_InLen);
-
- ND->inbuf = (APTR) xpar->xsp_Sub[1];
- ND->outbuf= xpar->xsp_OutBuf;
- ND->ulen = (UWORD) xpar->xsp_InLen;
- ND->clen = (UWORD) (xpar->xsp_OutBufLen-4);
-
- memset(ND->last,0,LASTSIZE);
- memset(ND->next,0,NEXTSIZE);
-
- if(((LONG)(xpar->xsp_OutLen = AsmPack(ND))) <0 || xpar->xsp_OutLen>xpar->xsp_InLen)
- {
- /* XpksPackReset(xpar); ist empty function */
- return XPKERR_EXPANSION;
- }
- return 0;
- }
-
- #ifdef __cplusplus
- extern "C"
- #endif
-
- LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
- {
- if(!xpar->xsp_Sub[1] && !(xpar->xsp_Sub[1] = (LONG) AllocMem(SCANBUFLEN,0)))
- return XPKERR_NOMEM;
-
- AsmUnpack((STRPTR) xpar->xsp_InBuf, (STRPTR)xpar->xsp_InBuf + xpar->xsp_InLen,
- (STRPTR)xpar->xsp_Sub[1], (STRPTR)xpar->xsp_Sub[1] + xpar->xsp_OutLen);
-
- UndoDelta((STRPTR)xpar->xsp_OutBuf, (STRPTR )xpar->xsp_Sub[1], xpar->xsp_OutLen);
-
- return 0;
- }
-
- #ifdef __cplusplus
- extern "C"
- #endif
-
- void __asm XpksUnpackFree(register __a0 struct XpkSubParams *xpar)
- {
- if (xpar->xsp_Sub[1]) FreeMem((APTR)xpar->xsp_Sub[1], SCANBUFLEN), xpar->xsp_Sub[1]=0;
- }
-